﻿// Author: Hristo Hristov
// Date: 28.08.11
// Revision 2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using ProjectMercury;

namespace NOVA.Scenery
{
    /// <summary>
    /// Creates a particle object for the scene.
    /// </summary>
    public class ParticleObject : ITransformable
    {
        #region Members
        Vector3 m_position;
        Quaternion m_rotation;
        Vector3 m_scale;
        string m_strType;
        BoundingBox m_boundingBox;
        string m_strName;
        Matrix m_controllerMatrix;
        bool m_bHasController;
        ParticleEffect m_particleEffect;
        bool m_bEnable;
        int m_iID;
        #endregion

        #region Properties

        /// <summary>
        /// Gets the ID of the particle object.
        /// </summary>
        public int ID { get { return m_iID; } }

        /// <summary>
        /// Gets or sets the current position of the particle object.
        /// </summary>
        public Vector3 Position
        {
            get
            {
                return m_position;
            }
            set
            {
                m_position = value;
            }
        }

        /// <summary>
        /// Gets or sets the current orientation of the particle object.
        /// </summary>
        public Quaternion Orientation
        {
            get
            {
                return m_rotation;
            }
            set
            {
                m_rotation = value;
            }
        }

        /// <summary>
        /// Not used for the particle object.
        /// </summary>
        public Vector3 Scale
        {
            get
            {
                return m_scale;
            }
            set
            {
                m_scale = value;
            }
        }

        public string Type
        {
            get
            {
                return m_strType;
            }
            set
            {
                m_strType = value;
            }
        }

        public BoundingBox BoundingBox
        {
            get { return m_boundingBox; }
        }

        /// <summary>
        /// Gets or sets the current name of the particle object.
        /// </summary>
        public string Name
        {
            get
            {
                return m_strName;
            }
            set
            {
                m_strName = value;
            }
        }

        public Matrix ControllerMatrix
        {
            get
            {
                return m_controllerMatrix;
            }
            set
            {
                m_controllerMatrix = value;
            }
        }

        public bool HasController
        {
            get
            {
                return m_bHasController;
            }
            set
            {
                m_bHasController = value;
            }
        }
        
        /// <summary>
        /// Gets the particle effect of the particle object.
        /// </summary>
        public ParticleEffect Effect
        {
            get { return m_particleEffect; }
        }
        #endregion

        #region Constructor

        /// <summary>
        /// Creates a particle object for the scene.
        /// </summary>
        public ParticleObject(Vector3 position, ParticleEffect effect)
        {
            m_position = position;
            m_rotation = Quaternion.Identity;
            m_scale = Vector3.One;

            m_particleEffect = effect;

            m_iID = Core.GetNextNodeID();

            m_strType = "ParticleEffect";
            m_strName = "ParticleEffect" + m_iID.ToString();

            // Active the emitters
            for (int i = 0; i < m_particleEffect.Emitters.Count; i++)
                m_particleEffect.Emitters[i].Initialise();  
        }
        #endregion

        /// <summary>
        /// Updates and fires the particles
        /// </summary>
        /// <param name="delta"></param>
        internal void Update(float delta, BoundingFrustum frustum)
        {
            m_particleEffect.Trigger(delta, ref m_position, ref frustum);
            
            m_particleEffect.Update(delta);
        }
    }
}
